﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using HCM_maps_website.Process.BLL;
using HCM_maps_website.Models;
using HCM_maps_website.Controllers;
using System.Web.Http;
using System.Net;
using System.Net.Http;
using System.Drawing;
using XichLoMapAPI.Models;

namespace XichLoMapAPI.Controllers
{
    public class MapController : ApiController
    {
        static string baseHost = "localhost:52612/";
        static readonly int[] centerXY = new int[] { 568, 670, 1083, 1282, 2139, 2585, 4331, 4994, 8712, 9948 };
        static int[] distanceXY     =    new int[] {588,  682, 1124, 1306, 2222, 2634, 4497, 5090, 9040, 10139};
        static PointF point1 = new PointF(10.773635f, 106.689385f);
        static PointF point2 = new PointF(10.771338f, 106.693228f);
        static int[] mapSize = new int[] { 3, 5, 8, 11, 18, 27, 38, 56, 74, 96 };

        int pwidth = 256; int pheight = 256;

        // GET: /Map/?longtitude=&latitude=
        public MapInfo Get(int w,int h,int zoomlv,double lat,double lon,bool mapType)
        {
            List<string> imgPath = new List<string>();
            string path = baseHost + (mapType ? "MapData/images/M_" : "MapData/images/S_");
            path += zoomlv.ToString() + "_";
            zoomlv--;

            PointF dis = new PointF(point1.Y - point2.Y, point1.X - point2.X);
            int[] pixelsDis = new int[] {centerXY[zoomlv*2]-distanceXY[zoomlv*2],centerXY[zoomlv*2+1]-distanceXY[zoomlv*2+1]};
            double[] pixelperCoordinate = new double[] { dis.X / pixelsDis[0], dis.Y / pixelsDis[1] };
            double[] rootCoordinate = new double[] { point1.Y - centerXY[zoomlv * 2] * pixelperCoordinate[0], point1.X - centerXY[zoomlv * 2+1] * pixelperCoordinate[1] };

            var x = (lat-rootCoordinate[1])/pixelperCoordinate[1];
            var y = (lon-rootCoordinate[0])/pixelperCoordinate[0];

            //caculate the image content the coordinate
            var numX = (int)(x / pheight);
            var numY = (int)(y / pwidth);

            //Calc num of pic
            var numRows = (h / pheight) + (h % pheight == 0 ? 0 : 1);
            var numCols = (w / pwidth) + (w % pwidth == 0 ? 0 : 1);
            var center = new Point(numRows/2,numCols/2);

            MapInfo info = new MapInfo();
            info.mapPics = new List<string>();
            var topleft = new Point(numX - center.X, numY - center.Y);
            var rightbottom = new Point(numX + (numRows - center.X), numY + (numCols - center.Y));

            if (topleft.X < 0)
            {
                topleft.X = 0;
                rightbottom.X -= topleft.X;
            }
            if (topleft.Y < 0)
            {
                topleft.Y = 0;
                rightbottom.Y -= topleft.Y;
            }
            while (rightbottom.X > mapSize[zoomlv * 2])
            {
                rightbottom.X--;
                topleft.X--;
                if (topleft.X < 0)
                    topleft.X = 0;
            }
            while (rightbottom.Y > mapSize[zoomlv * 2 + 1])
            {
                rightbottom.Y--;
                topleft.Y--;
                if (topleft.Y < 0)
                    topleft.Y = 0;
            }
            for (int i = topleft.X; i < rightbottom.X; i++)
            {
                for (int j = topleft.Y; j < rightbottom.Y; j++)
                {
                    info.mapPics.Add(path + i.ToString("00")+"_"+j.ToString("00"));
                }
            }
            //info.mapPics;
            info.pixels = new Point((int)x % pheight + center.X*pheight,(int)y % pwidth + center.Y*pwidth);

            return info;
        }

        //GET :/Map/keyword
        public SearchResult Get(string keyword)
        {
            return SearchBLL.Search(keyword);
        }

        //GET :/Map
        //Get current coordinate
        public Coordinate Get()
        {
            return null;
        }

        //GET
        //Find street
        public List<GraphNodeInfoEx> Get(double fromX, double fromY, double toX, double toY)
        {
            return DirectionService.ShortestPath(new Coordinate(fromX, fromY), new Coordinate(toX, toY));
        }
    }
}
